package com.yeskery.nut.core;

import com.yeskery.nut.http.controller.StaticResourceController;

import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * Controller 管理器接口
 * @author sprout
 * 2019-03-16 10:01
 * @version 1.0
 */
public interface ControllerManager {

	/**
	 * 获取管理器中注册的所有 Controller
	 * @return 管理器中注册的所有 Controller
	 */
	Map<ControllerMetadata, Controller> getAllController();

	/**
	 * 向管理器注册一个 Controller
	 * @param controller Controller 对象
	 * @param controllerSource Controller 来源
	 * @param path 需要注册的路径
	 * @param alias 需要注册的别名数组
	 */
	void registerController(Controller controller, ControllerSource controllerSource, String path, String[] alias);

	/**
	 * 向管理器注册一个 Controller
	 * @param controller Controller 对象
	 * @param path 需要注册的路径
	 * @param alias 需要注册的别名数组
	 */
	default void registerController(Controller controller, String path, String[] alias) {
		registerController(controller, ControllerSource.STATIC, path, alias);
	}

	/**
	 * 向管理器注册一个 Controller
	 * @param controller Controller 对象
	 * @param controllerSource Controller 来源
	 * @param path 需要注册的路径
	 */
	default void registerController(Controller controller, ControllerSource controllerSource, String path) {
		registerController(controller, controllerSource, path, new String[0]);
	}

	/**
	 * 向管理器注册一个 Controller
	 * @param controller Controller 对象
	 * @param path 需要注册的路径
	 */
	default void registerController(Controller controller, String path) {
		registerController(controller, ControllerSource.STATIC, path);
	}

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param controllerSource Controller 来源
	 * @param methods 需要注册的HTTP 请求方法
	 * @param path 需要注册的路径
	 * @param alias 需要注册的别名数组
	 */
	void registerController(RequestHandler requestHandler, ControllerSource controllerSource, Set<Method> methods, String path, String[] alias);

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param controllerSource Controller 来源
	 * @param methods 需要注册的HTTP 请求方法
	 * @param path 需要注册的路径
	 */
	default void registerController(RequestHandler requestHandler, ControllerSource controllerSource, Set<Method> methods, String path) {
		registerController(requestHandler, controllerSource, methods, path, new String[0]);
	}

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param methods 需要注册的HTTP 请求方法
	 * @param path 需要注册的路径
	 * @param alias 需要注册的别名数组
	 */
	default void registerController(RequestHandler requestHandler, Set<Method> methods, String path, String[] alias) {
		registerController(requestHandler, ControllerSource.LAMBDA, methods, path, alias);
	}

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param methods 需要注册的HTTP 请求方法
	 * @param path 需要注册的路径
	 */
	default void registerController(RequestHandler requestHandler, Set<Method> methods, String path) {
		registerController(requestHandler, ControllerSource.LAMBDA, methods, path);
	}

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param method 请求方法
	 * @param path 需要注册的路径
	 * @param alias 需要注册的别名数组
	 */
	default void registerController(RequestHandler requestHandler, Method method, String path, String[] alias) {
		registerController(requestHandler, ControllerSource.LAMBDA, method, path, alias);
	}

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param method 请求支持的方法
	 * @param path 需要注册的路径
	 */
	default void registerController(RequestHandler requestHandler, Method method, String path) {
		registerController(requestHandler, ControllerSource.LAMBDA, method, path);
	}

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param controllerSource Controller 来源
	 * @param method 需要注册的HTTP 请求方法
	 * @param path 需要注册的路径
	 * @param alias 需要注册的别名数组
	 */
	default void registerController(RequestHandler requestHandler, ControllerSource controllerSource, Method method, String path, String[] alias) {
		registerController(requestHandler, controllerSource, Collections.singleton(method), path, alias);
	}

	/**
	 * 向管理器注册一个 RequestHandler
	 * @param requestHandler 请求处理函数
	 * @param controllerSource Controller 来源
	 * @param method 需要注册的HTTP 请求方法
	 * @param path 需要注册的路径
	 */
	default void registerController(RequestHandler requestHandler, ControllerSource controllerSource, Method method, String path) {
		registerController(requestHandler, controllerSource, Collections.singleton(method), path, new String[0]);
	}

	/**
	 * 移除Controller
	 * @param controller 注册的controller
	 * @return 移除是否成功
	 */
	boolean removeController(Controller controller);

	/**
	 * 移除Controller
	 * @param controllerId Controller id
	 * @return 移除是否成功
	 */
	boolean removeController(long controllerId);

	/**
	 * 移除Controller
	 * @param path Controller 注册路径或别名
	 * @return 移除是否成功
	 */
	boolean removeController(String path);

	/**
	 * 添加静态资源访问路径
	 * @param paths 需要添加的静态资源路径数组
	 */
	void addStaticResourcePaths(String... paths);

	/**
	 * 添加静态资源文件路径
	 * @param dirs 需要添加静态资源文件路径
	 */
	void addStaticResourceDirs(String... dirs);

	/**
	 * 获取静态资源访问路径
	 * @return 静态资源访问路径
	 */
	Set<Path> getStaticResourcePaths();

	/**
	 * 获取静态资源文件路径
	 * @return 静态资源文件路径
	 */
	Set<String> getStaticResourceDirs();

	/**
	 * 设置静态资源目录预览是否开启
	 * @param staticDirectoryPreview 静态资源目录预览是否开启
	 */
	void setStaticDirectoryPreview(boolean staticDirectoryPreview);

	/**
	 * 设置首页 Controller
	 * @param controller Controller 对象
	 */
	void setIndexController(Controller controller);

	/**
	 * 设置默认的错误 Controller
	 * @param controller Controller 对象
	 */
	void setErrorController(Controller controller);

	/**
	 * 设置默认的 404 Controller
	 * @param controller Controller 对象
	 */
	void setNotFoundController(Controller controller);

	/**
	 * 设置静态资源 Controller 对象
	 * @param controller 静态资源 Controller 对象
	 */
	void setStaticResourceController(StaticResourceController controller);

	/**
	 * 通过请求路径查询对应的 Controller 对象
	 * @param path 请求的路径
	 * @return Controller 对象
	 */
	Controller findController(String path);

	/**
	 * 通过请求路径查询对应的 Controller 对象，精确查找，可能会查询不到
	 * @param path 请求的路径
	 * @return Controller 对象
	 */
	Controller getController(String path);

	/**
	 * 获取首页 Controller 对象
	 * @return 首页 Controller 对象
	 */
	Controller getIndexController();

	/**
	 * 获取错误 Controller 对象
	 * @return 错误 Controller 对象
	 */
	Controller getErrorController();

	/**
	 * 获取 404 Controller 对象
	 * @return 404 Controller 对象
	 */
	Controller getNotFoundController();

	/**
	 * 获取静态资源 Controller 对象
	 * @return 静态资源 Controller 对象
	 */
	StaticResourceController getStaticResourceController();
}
